package com.sinosoft.taxbenefit.core.AccountChange.biz.service.impl;

import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.sinosoft.platform.base.TaxBaseService;
import com.sinosoft.platform.common.config.SystemConstants;
import com.sinosoft.platform.common.exception.BusinessDataErrException;
import com.sinosoft.platform.common.util.DateUtil;
import com.sinosoft.platform.common.util.StringUtil;
import com.sinosoft.taxbenefit.api.base.EBResultCodeDTO;
import com.sinosoft.taxbenefit.api.base.HXResultCodeDTO;
import com.sinosoft.taxbenefit.api.config.ENUM_BZ_RESPONSE_RESULT;
import com.sinosoft.taxbenefit.api.config.ENUM_DISPOSE_TYPE;
import com.sinosoft.taxbenefit.api.config.ENUM_SENDSERVICE_CODE;
import com.sinosoft.taxbenefit.api.dto.request.TaxFaulTaskDTO;
import com.sinosoft.taxbenefit.api.dto.request.accountchange.ReqAccountCoreDTO;
import com.sinosoft.taxbenefit.api.dto.request.accountchange.ReqAccountInfoDTO;
import com.sinosoft.taxbenefit.api.dto.request.accountchange.ReqAccountMoreChangeCoreDTO;
import com.sinosoft.taxbenefit.api.dto.request.accountchange.ReqAccountMoreChangeDTO;
import com.sinosoft.taxbenefit.api.dto.request.base.CoreRequestHead;
import com.sinosoft.taxbenefit.api.dto.request.base.ParamHeadDTO;
import com.sinosoft.taxbenefit.api.dto.request.base.ThirdSendResponseDTO;
import com.sinosoft.taxbenefit.api.dto.response.accountchange.AccountChangeResultDTO;
import com.sinosoft.taxbenefit.core.AccountChange.biz.service.AccountChangeService;
import com.sinosoft.taxbenefit.core.AccountChange.dto.AccountChangeAffDTO;
import com.sinosoft.taxbenefit.core.AccountChange.dto.AccountChangeDTO;
import com.sinosoft.taxbenefit.core.AccountChange.dto.ReqAccountChangeDTO;
import com.sinosoft.taxbenefit.core.AccountChange.dto.ResAccountChangeDTO;
import com.sinosoft.taxbenefit.core.common.biz.service.CommonCodeService;
import com.sinosoft.taxbenefit.core.common.config.ENUM_BUSINESS_RESULR;
import com.sinosoft.taxbenefit.core.common.config.ENUM_EBAO_SERVICE_PORT_CODE;
import com.sinosoft.taxbenefit.core.common.config.ENUM_HX_SERVICE_PORT_CODE;
import com.sinosoft.taxbenefit.core.common.config.ENUM_RC_STATE;
import com.sinosoft.taxbenefit.core.common.config.ENUM_RESULT_CODE;
import com.sinosoft.taxbenefit.core.common.dto.BookSequenceDTO;
import com.sinosoft.taxbenefit.core.common.dto.EbaoServerPortDTO;
import com.sinosoft.taxbenefit.core.common.dto.ReqBusinessDTO;
import com.sinosoft.taxbenefit.core.common.dto.ReqBusinessDetailDTO;
import com.sinosoft.taxbenefit.core.common.dto.SendLogDTO;
import com.sinosoft.taxbenefit.core.common.dto.ThirdSendDTO;
import com.sinosoft.taxbenefit.core.ebaowebservice.AsynResultQueryService;
import com.sinosoft.taxbenefit.core.ebaowebservice.AsynResultQueryService_Service;
import com.sinosoft.taxbenefit.core.ebaowebservice.PolicyAccountService;
import com.sinosoft.taxbenefit.core.ebaowebservice.PolicyAccountService_Service;
import com.sinosoft.taxbenefit.core.ebaowebservice.ResponseBody;
import com.sinosoft.taxbenefit.core.ebaowebservice.ResponseHeader;
import com.sinosoft.taxbenefit.core.ebaowebservice.ResponseJSON;
import com.sinosoft.taxbenefit.core.faultTask.biz.service.FaultTaskService;
import com.sinosoft.taxbenefit.core.generated.mapper.TaxContAccountTrackMapper;
import com.sinosoft.taxbenefit.core.generated.mapper.TaxFaultTaskMapper;
import com.sinosoft.taxbenefit.core.generated.model.TaxContAccountTrack;
import com.sinosoft.taxbenefit.core.generated.model.TaxFaultTask;
import com.sinosoft.taxbenefit.core.transCode.biz.service.TransCodeService;
/**
 * 账户变更上传具体实现
 * @author zhangyu
 * @date 2016年3月14日 下午1:29:39
 */
@Service
public class AccountChangeServiceImpl extends TaxBaseService implements AccountChangeService{
    @Autowired 
	private TaxContAccountTrackMapper taxContAccountTrackMapper;
    @Autowired
    CommonCodeService commonCodeService;
    @Autowired
	private FaultTaskService faultTaskService;
	@Autowired
	TaxFaultTaskMapper taxFaultTaskMapper;//异常任务
    @Autowired
	TransCodeService transCodeService;// 转码

	@Override
	public ThirdSendResponseDTO addAccountChange(ReqAccountInfoDTO reqAccountInfoDTO, ParamHeadDTO paramHeadDTO) {
		ThirdSendResponseDTO thirdSendResponse = new ThirdSendResponseDTO();
		List<ReqBusinessDetailDTO> reqBusinessDetailList = new ArrayList<ReqBusinessDetailDTO>();   
		try{ 
    	   	ReqBusinessDTO businessDTO = commonCodeService.initReqBusinessDTO();
    	    logger.info("单笔账户变更上传（核心请求）JSON 体数据内容："+JSONObject.toJSONString(reqAccountInfoDTO));
    	    //1.将账户变更请求dto转换为中保信账户变更请求dto
    	    ReqAccountChangeDTO reqAccountChangeDTO = this.tansforDTO(reqAccountInfoDTO);
			//2.调用中保信接口服务,获得返回结果   存储调用中保信日志表
			ThirdSendDTO thirdSendDTO = commonCodeService.createThirdSend(ENUM_EBAO_SERVICE_PORT_CODE.ACCONUT_CHANGE.code(), paramHeadDTO, reqAccountChangeDTO); 
			logger.info("单笔账户变更上传（请求中保信）JSON 数据内容："+JSONObject.toJSONString(thirdSendDTO));
			Holder<ResponseHeader> responseHeaderHolder = new Holder<ResponseHeader>();
			Holder<ResponseBody> responseBodyHolder = new Holder<ResponseBody>();
			EbaoServerPortDTO ebaoServerPort = commonCodeService.queryEBaoServerInfoByPortCode(ENUM_EBAO_SERVICE_PORT_CODE.ACCONUT_CHANGE.code());
			String portUrl = ebaoServerPort.getPortUrl();
			URL wsdlLocation = new URL(portUrl);
			PolicyAccountService_Service service = new PolicyAccountService_Service(wsdlLocation);
			PolicyAccountService  servicePort = service.getPolicyAccountServicePort();
			BindingProvider bp = (BindingProvider) servicePort;
			bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, portUrl);
			servicePort.account(thirdSendDTO.getHead(),  thirdSendDTO.getBody(), responseHeaderHolder, responseBodyHolder);
			ResponseHeader responseHeader = responseHeaderHolder.value;
			ResponseBody responseBody = responseBodyHolder.value;
			logger.info("单笔账户变更上传（中保信响应）JSON 数据内容："+responseBody.getJsonString());
			// 封装中保信返回报文
			ResponseJSON responseJSON = new ResponseJSON();
			responseJSON.setResponseBody(responseBody);
			responseJSON.setResponseHeader(responseHeader);
			// 封装发送报文日志对象
			SendLogDTO sendLog = new SendLogDTO();
			sendLog.setSerialNo(paramHeadDTO.getSerialNo());
			sendLog.setPortCode(ENUM_EBAO_SERVICE_PORT_CODE.ACCONUT_CHANGE.code());
			sendLog.setRequestContent(JSONObject.toJSONString(thirdSendDTO));
			sendLog.setResponseContent(JSONObject.toJSONString(responseJSON));
			sendLog.setTargetCode(ENUM_SENDSERVICE_CODE.EBAO.code());
			sendLog.setState(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
			sendLog.setDescription(ENUM_BZ_RESPONSE_RESULT.SUCCESS.description());
			commonCodeService.addLogSend(sendLog);
			
			// 3.封装返回核心dto;
			if (ENUM_RESULT_CODE.SUCCESS.code().equals(responseHeader.getResultCode())
					|| ENUM_RESULT_CODE.INPUT_LOCALITY_SUCCESS.code().equals(responseHeader.getResultCode())) {
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
				thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.SUCCESS.description());
			}else{
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.FAIL.code());
				List list = responseHeader.getResultMessage().getMessage();
				if(list != null && list.size() > 0){
					StringBuffer sbStr = new StringBuffer(); 
					for(String mess : responseHeader.getResultMessage().getMessage()){
						sbStr.append(mess).append("|");
					}
					String message = sbStr.substring(0, sbStr.length()-1).toString();
					thirdSendResponse.setResultDesc(message);
				}else{
					thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.FAIL.description());
				}
			}
			AccountChangeResultDTO accountChangeResultDTO=new AccountChangeResultDTO();
			boolean isRegisterFaulTask = false;
			if(!StringUtil.isEmpty(responseBody.getJsonString())){
				//封装返回核心的DTO
				ResAccountChangeDTO resAccountChangeDTO = JSONObject.parseObject(responseBody.getJsonString(), ResAccountChangeDTO.class);
				if (null != resAccountChangeDTO.getSavingAccountFeeList()) {
					accountChangeResultDTO.setAccountFeeSequenceNo(resAccountChangeDTO.getSavingAccountFeeList().get(0).getAccountFeeSequenceNo());
					EBResultCodeDTO eBResultCode = resAccountChangeDTO.getSavingAccountFeeList().get(0).getResult();
					HXResultCodeDTO hxResultCode = new HXResultCodeDTO();
					hxResultCode.setResultCode(eBResultCode.getResultCode());
					String message = "";
					if(null != eBResultCode.getResultMessage()){
						StringBuffer sbStr = new StringBuffer(); 
						for(String mess : eBResultCode.getResultMessage()){
							sbStr.append(mess).append("|");
						}
						message = sbStr.substring(0, sbStr.length()-1).toString();
					}
					hxResultCode.setResultMessage(message);
					accountChangeResultDTO.setComFeeId(resAccountChangeDTO.getSavingAccountFeeList().get(0).getComFeeId());
					accountChangeResultDTO.setResult(hxResultCode);
					accountChangeResultDTO.setBizNo(reqAccountInfoDTO.getBizNo());
					thirdSendResponse.setResJson(accountChangeResultDTO);
					if(ENUM_RESULT_CODE.SUCCESS.code().equals(eBResultCode.getResultCode())){
						businessDTO.setReqSuccessNum(businessDTO.getReqSuccessNum() + 1);
						addAccount(reqAccountInfoDTO, accountChangeResultDTO);
					}else{
						businessDTO.setReqFailNum(businessDTO.getReqFailNum() + 1);
						ReqBusinessDetailDTO reqBusinessDetailDTO = commonCodeService.initReqBusinessDetailDTO(paramHeadDTO);
						reqBusinessDetailDTO.setResultCode(ENUM_BUSINESS_RESULR.FAIL.code());
						reqBusinessDetailDTO.setResultMessage(message);
						reqBusinessDetailList.add(reqBusinessDetailDTO);
					}
					isRegisterFaulTask = true;
				}else{
					BookSequenceDTO bookSequence = JSONObject.parseObject(responseBody.getJsonString(), BookSequenceDTO.class);
					TaxFaulTaskDTO taxFaultTask = new TaxFaulTaskDTO();
					taxFaultTask.setSerialNo(paramHeadDTO.getSerialNo());
					taxFaultTask.setServerPortCode(paramHeadDTO.getPortCode());
					taxFaultTask.setServerPortName(paramHeadDTO.getPortName());
					taxFaultTask.setAreaCode(paramHeadDTO.getAreaCode());
					taxFaultTask.setDisposeType(ENUM_DISPOSE_TYPE.APPOINTMENT.code());
					taxFaultTask.setBookSequenceNo(bookSequence.getBookingSequenceNo());
					faultTaskService.addTaxFaultTask(taxFaultTask);
				}
			}else{
				businessDTO.setReqFailNum(responseHeader.getRecordNum());
				ReqBusinessDetailDTO reqBusinessDetailDTO = commonCodeService.initReqBusinessDetailDTO(paramHeadDTO);
				reqBusinessDetailDTO.setResultCode(ENUM_BUSINESS_RESULR.FAIL.code());
				reqBusinessDetailDTO.setResultMessage(thirdSendResponse.getResultDesc());
				reqBusinessDetailList.add(reqBusinessDetailDTO);
			}
			if (isRegisterFaulTask) {
				// 添加失败交易记录
				commonCodeService.addReqBusinessDetail(reqBusinessDetailList);
				businessDTO.setRequetNum(responseHeader.getRecordNum());
				commonCodeService.addReqBusinessCollate(businessDTO);
			}
		}catch(Exception ex){
			logger.error("单笔账户变更上传失败"+ex.getMessage());
			thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.code());
			thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.description());
			// 存储任务表
			TaxFaulTaskDTO taxFaultTask = new TaxFaulTaskDTO();
			taxFaultTask.setServerPortCode(paramHeadDTO.getPortCode());
			taxFaultTask.setServerPortName(paramHeadDTO.getPortName());
			taxFaultTask.setAreaCode(paramHeadDTO.getAreaCode());
			taxFaultTask.setSerialNo(paramHeadDTO.getSerialNo());
			taxFaultTask.setDisposeType(ENUM_DISPOSE_TYPE.ERROR.code());
			faultTaskService.addTaxFaultTask(taxFaultTask);
			ex.printStackTrace();
		}	
	    logger.error("单笔账户变更上传后置处理结束!");
		return thirdSendResponse;
	}
	/**
	 * 数据持久化
	 * @param reqAccountInfoDTO
	 * @param accountChangeResultDTO
	 */
	private void addAccount(ReqAccountInfoDTO reqAccountInfoDTO,
			AccountChangeResultDTO accountChangeResultDTO) {
		//封装持久化对象
		try {
			TaxContAccountTrack taxContAccountTrack=new TaxContAccountTrack();
			taxContAccountTrack.setContNo(reqAccountInfoDTO.getPolicyNo());
			taxContAccountTrack.setRiskCode(reqAccountInfoDTO.getComCoverageCode());
			taxContAccountTrack.setRiskName(reqAccountInfoDTO.getComCoverageName());
			taxContAccountTrack.setFeeId(accountChangeResultDTO.getComFeeId());
			taxContAccountTrack.setFeeDate(DateUtil.parseDate(reqAccountInfoDTO.getFeeDate()));
			taxContAccountTrack.setFeeType(reqAccountInfoDTO.getFeeType());
			taxContAccountTrack.setFeeAmount(reqAccountInfoDTO.getFeeAmount());
			taxContAccountTrack.setAffectStartDate(DateUtil.parseDate(reqAccountInfoDTO.getRiskCoverageStartDate()));
			taxContAccountTrack.setAffectEndDate(DateUtil.parseDate(reqAccountInfoDTO.getRiskCoverageEndDate()));
			taxContAccountTrack.setInterestRate(reqAccountInfoDTO.getInterestRate());
			taxContAccountTrack.setBalanceAmount(reqAccountInfoDTO.getBalanceAmount());
			taxContAccountTrack.setRebackDetailId(reqAccountInfoDTO.getRevComFeeId());
			taxContAccountTrack.setRcState(ENUM_RC_STATE.EFFECTIVE.getCode());
			taxContAccountTrack.setCreateDate(DateUtil.getCurrentDate());
			taxContAccountTrack.setModifyDate(DateUtil.getCurrentDate());
			taxContAccountTrack.setCreatorId(SystemConstants.SYS_OPERATOR);
			taxContAccountTrack.setModifierId(SystemConstants.SYS_OPERATOR);
			taxContAccountTrackMapper.insert(taxContAccountTrack);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("账户变更上传数据持久化失败"+e.getMessage());
		}
	}
	/**
	 * 核心请求DTO转换为中保信请求DTO
	 * @param accountInfoDTO
	 * @return
	 */
	public ReqAccountChangeDTO tansforDTO(ReqAccountInfoDTO accountInfoDTO) {
		ReqAccountChangeDTO reqAccountChangeDTO = new ReqAccountChangeDTO();
		AccountChangeDTO savingAccountFee = new AccountChangeDTO();
		List<AccountChangeDTO> accountChangeList = new ArrayList<AccountChangeDTO>();
		savingAccountFee.setPolicyNo(accountInfoDTO.getPolicyNo());
		savingAccountFee.setSequenceNo(accountInfoDTO.getSequenceNo());
		savingAccountFee.setComCoverageCode(accountInfoDTO.getComCoverageCode());
		savingAccountFee.setCoveragePackageCode(accountInfoDTO.getCoveragePackageCode());
		savingAccountFee.setComCoverageName(accountInfoDTO.getComCoverageName());
		savingAccountFee.setComFeeId(accountInfoDTO.getComFeeId());
		savingAccountFee.setFeeDate(accountInfoDTO.getFeeDate());
		savingAccountFee.setFeeType(accountInfoDTO.getFeeType());
		savingAccountFee.setFeeAmount(accountInfoDTO.getFeeAmount());
		savingAccountFee.setRiskComCoverageCode(accountInfoDTO.getRiskComCoverageCode());
		savingAccountFee.setRiskCoverageStartDate(accountInfoDTO.getRiskCoverageStartDate());
		savingAccountFee.setBalanceAmount(accountInfoDTO.getBalanceAmount());
		savingAccountFee.setRevComFeeId(accountInfoDTO.getRevComFeeId());
		savingAccountFee.setAdjustReason(accountInfoDTO.getAdjustReason());
		savingAccountFee.setRiskCoverageEndDate(accountInfoDTO.getRiskCoverageEndDate());
		savingAccountFee.setInterestRate(accountInfoDTO.getInterestRate());
		accountChangeList.add(savingAccountFee);
		reqAccountChangeDTO.setSavingAccountFeeList(accountChangeList);
		return reqAccountChangeDTO;
	}
	@Override
	public ThirdSendResponseDTO addAccountListChange(
			List<ReqAccountInfoDTO> reqAccountInfoList, ParamHeadDTO paramHeadDTO) {
		ThirdSendResponseDTO thirdSendResponse = new ThirdSendResponseDTO();
		List<ReqBusinessDetailDTO> reqBusinessDetailList = new ArrayList<ReqBusinessDetailDTO>();
		try {
			ReqBusinessDTO businessDTO = commonCodeService.initReqBusinessDTO();
    	    logger.info("多笔账户变更上传（核心请求）JSON 体数据内容："+JSONObject.toJSONString(reqAccountInfoList));
    	    //1.将账户变更请求dto转换为中保信账户变更请求dto
    	    ReqAccountChangeDTO reqAccountChangeDTO = this.transforDTO(reqAccountInfoList);
			//2.调用中保信接口服务,获得返回结果   存储调用中保信日志表
			ThirdSendDTO thirdSendDTO = commonCodeService.createThirdSend(ENUM_EBAO_SERVICE_PORT_CODE.ACCONUT_CHANGE.code(), paramHeadDTO, reqAccountChangeDTO);
			logger.info("多笔账户变更上传（请求中保信）JSON 数据内容："+JSONObject.toJSONString(thirdSendDTO));
			Holder<ResponseHeader> responseHeaderHolder = new Holder<ResponseHeader>();
			Holder<ResponseBody> responseBodyHolder = new Holder<ResponseBody>();
			EbaoServerPortDTO ebaoServerPort = commonCodeService.queryEBaoServerInfoByPortCode(ENUM_EBAO_SERVICE_PORT_CODE.ACCONUT_CHANGE.code());
			String portUrl = ebaoServerPort.getPortUrl();
			URL wsdlLocation = new URL(portUrl);
			PolicyAccountService_Service service = new PolicyAccountService_Service(wsdlLocation);
			PolicyAccountService  servicePort = service.getPolicyAccountServicePort();
			BindingProvider bp = (BindingProvider) servicePort;
			bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, portUrl);
			servicePort.account(thirdSendDTO.getHead(),  thirdSendDTO.getBody(), responseHeaderHolder, responseBodyHolder);
			ResponseHeader responseHeader = responseHeaderHolder.value;
			ResponseBody responseBody = responseBodyHolder.value;
			logger.info("多笔账户变更上传（中保信响应）JSON 数据内容："+responseBody.getJsonString());
			// 封装中保信返回报文
			ResponseJSON responseJSON = new ResponseJSON();
			responseJSON.setResponseBody(responseBody);
			responseJSON.setResponseHeader(responseHeader);
			// 封装发送报文日志对象
			SendLogDTO sendLog = new SendLogDTO();
			sendLog.setSerialNo(paramHeadDTO.getSerialNo());
			sendLog.setPortCode(ENUM_EBAO_SERVICE_PORT_CODE.ACCONUT_CHANGE.code());
			sendLog.setRequestContent(JSONObject.toJSONString(thirdSendDTO));
			sendLog.setResponseContent(JSONObject.toJSONString(responseJSON));
			sendLog.setTargetCode(ENUM_SENDSERVICE_CODE.EBAO.code());
			sendLog.setState(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
			sendLog.setDescription(ENUM_BZ_RESPONSE_RESULT.SUCCESS.description());
			commonCodeService.addLogSend(sendLog);
			// 3.封装返回核心dto;
			if (ENUM_RESULT_CODE.SUCCESS.code().equals(responseHeader.getResultCode())
					|| ENUM_RESULT_CODE.INPUT_LOCALITY_SUCCESS.code().equals(responseHeader.getResultCode())) {
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
				thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.SUCCESS.description());
			}else{
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.FAIL.code());
				List list = responseHeader.getResultMessage().getMessage();
				if(list != null && list.size() > 0){
					StringBuffer sbStr = new StringBuffer(); 
					for(String mess : responseHeader.getResultMessage().getMessage()){
						sbStr.append(mess).append("|");
					}
					String message = sbStr.substring(0, sbStr.length()-1).toString();
					thirdSendResponse.setResultDesc(message);
				}else{
					thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.FAIL.description());
				}
			}
			boolean isRegisterFaulTask = false;
			if(!StringUtil.isEmpty(responseBody.getJsonString())){
				//封装返回核心的DTO
				List<AccountChangeResultDTO> accountChangeResultList = new ArrayList<AccountChangeResultDTO>();
				ResAccountChangeDTO resAccountChangeDTO = JSONObject.parseObject(responseBody.getJsonString(), ResAccountChangeDTO.class);
				if (null != resAccountChangeDTO.getSavingAccountFeeList()) {
					// 成功记录数
					Integer successNum = 0;
					// 失败记录数
					Integer failNum = 0;
					//把中保信返回的对象中的每一条信息都传给核心返回的DTO
					for (AccountChangeAffDTO accountChangeAffDTO : resAccountChangeDTO.getSavingAccountFeeList()) {
						AccountChangeResultDTO accountChangeResultDTO=new AccountChangeResultDTO();
						accountChangeResultDTO.setComFeeId(accountChangeAffDTO.getComFeeId());
						accountChangeResultDTO.setAccountFeeSequenceNo(accountChangeAffDTO.getAccountFeeSequenceNo());
						for (ReqAccountInfoDTO reqAccountInfoDTO : reqAccountInfoList) {
							if(reqAccountInfoDTO.getComFeeId().equals(accountChangeAffDTO.getComFeeId())){
								accountChangeResultDTO.setBizNo(reqAccountInfoDTO.getBizNo());
								EBResultCodeDTO eBResultCode = accountChangeAffDTO.getResult();
								HXResultCodeDTO hxResultCode = new HXResultCodeDTO();
								hxResultCode.setResultCode(eBResultCode.getResultCode());
								String message = "";
								if(null != eBResultCode.getResultMessage()){
									StringBuffer sbStr = new StringBuffer(); 
									for(String mess : eBResultCode.getResultMessage()){
										sbStr.append(mess).append("|");
									}
									message = sbStr.substring(0, sbStr.length()-1).toString();
								}
								hxResultCode.setResultMessage(message);
								accountChangeResultDTO.setResult(hxResultCode);
								accountChangeResultList.add(accountChangeResultDTO);
								//记录成功和失败记录数
								if(ENUM_RESULT_CODE.SUCCESS.code().equals(eBResultCode.getResultCode())){
									successNum+=1;
									addAccountMore(reqAccountInfoDTO, accountChangeResultDTO);
								}else{
									failNum+=1;
									ReqBusinessDetailDTO reqBusinessDetailDTO = commonCodeService.initReqBusinessDetailDTO(paramHeadDTO);
									reqBusinessDetailDTO.setResultCode(ENUM_BUSINESS_RESULR.FAIL.code());
									reqBusinessDetailDTO.setResultMessage(message);
									reqBusinessDetailList.add(reqBusinessDetailDTO);
								}
							}
						}
					}
					// 登记请求记录
					businessDTO.setReqSuccessNum(successNum);
					businessDTO.setReqFailNum(failNum);
					thirdSendResponse.setResJson(accountChangeResultList);
					isRegisterFaulTask = true;
				}else{
					BookSequenceDTO bookSequence = JSONObject.parseObject(responseBody.getJsonString(), BookSequenceDTO.class);
					TaxFaulTaskDTO taxFaultTask = new TaxFaulTaskDTO();
					taxFaultTask.setSerialNo(paramHeadDTO.getSerialNo());
					taxFaultTask.setServerPortCode(paramHeadDTO.getPortCode());
					taxFaultTask.setServerPortName(paramHeadDTO.getPortName());
					taxFaultTask.setAreaCode(paramHeadDTO.getAreaCode());
					taxFaultTask.setDisposeType(ENUM_DISPOSE_TYPE.APPOINTMENT.code());
					taxFaultTask.setBookSequenceNo(bookSequence.getBookingSequenceNo());
					faultTaskService.addTaxFaultTask(taxFaultTask);
				}
			}else{
				businessDTO.setReqFailNum(responseHeader.getRecordNum());
				for (int i = 0; i < responseHeader.getRecordNum(); i++) {
					ReqBusinessDetailDTO reqBusinessDetailDTO = commonCodeService.initReqBusinessDetailDTO(paramHeadDTO);
					reqBusinessDetailDTO.setResultCode(ENUM_BUSINESS_RESULR.FAIL.code());
					reqBusinessDetailDTO.setResultMessage(thirdSendResponse.getResultDesc());
					reqBusinessDetailList.add(reqBusinessDetailDTO);
				}
			}
			if (isRegisterFaulTask) {
				commonCodeService.addReqBusinessDetail(reqBusinessDetailList);
				businessDTO.setRequetNum(responseHeader.getRecordNum());
				commonCodeService.addReqBusinessCollate(businessDTO);			
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("多笔账户变更上传失败"+e.getMessage());
			thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.code());
			thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.description());
			// 存储任务表
			TaxFaulTaskDTO taxFaultTask = new TaxFaulTaskDTO();
			taxFaultTask.setServerPortCode(paramHeadDTO.getPortCode());
			taxFaultTask.setServerPortName(paramHeadDTO.getPortName());
			taxFaultTask.setAreaCode(paramHeadDTO.getAreaCode());
			taxFaultTask.setSerialNo(paramHeadDTO.getSerialNo());
			taxFaultTask.setDisposeType(ENUM_DISPOSE_TYPE.ERROR.code());
			faultTaskService.addTaxFaultTask(taxFaultTask);
		}
		logger.error("多笔账户变更上传后置处理结束!");
		return thirdSendResponse;
	}
	/**
	 * 核心请求DTO转换为中保信DTO
	 * @param accountInfoDTO
	 * @return
	 */
	public ReqAccountChangeDTO transforDTO(List<ReqAccountInfoDTO> reqAccountInfoList) {
		ReqAccountChangeDTO reqAccountChangeDTO=new ReqAccountChangeDTO();
		List<AccountChangeDTO> accountChangeList=new ArrayList<AccountChangeDTO>();
		//遍历核心的账户变更上传列表
		for(ReqAccountInfoDTO reqAccountInfoDTO : reqAccountInfoList){
			AccountChangeDTO savingAccountFee=new AccountChangeDTO();
			savingAccountFee.setPolicyNo(reqAccountInfoDTO.getPolicyNo());
			savingAccountFee.setSequenceNo(reqAccountInfoDTO.getSequenceNo());
			savingAccountFee.setComCoverageCode(reqAccountInfoDTO.getComCoverageCode());
			savingAccountFee.setCoveragePackageCode(reqAccountInfoDTO.getCoveragePackageCode());
			savingAccountFee.setComCoverageName(reqAccountInfoDTO.getComCoverageName());
			savingAccountFee.setComFeeId(reqAccountInfoDTO.getComFeeId());
			savingAccountFee.setFeeDate(reqAccountInfoDTO.getFeeDate());
			savingAccountFee.setFeeType(reqAccountInfoDTO.getFeeType());
			savingAccountFee.setFeeAmount(reqAccountInfoDTO.getFeeAmount());
			savingAccountFee.setRiskComCoverageCode(reqAccountInfoDTO.getRiskComCoverageCode());
			savingAccountFee.setRiskCoverageStartDate(reqAccountInfoDTO.getRiskCoverageStartDate());
			savingAccountFee.setBalanceAmount(reqAccountInfoDTO.getBalanceAmount());
			savingAccountFee.setRevComFeeId(reqAccountInfoDTO.getRevComFeeId());
			savingAccountFee.setAdjustReason(reqAccountInfoDTO.getAdjustReason());
			savingAccountFee.setRiskCoverageEndDate(reqAccountInfoDTO.getRiskCoverageEndDate());
			savingAccountFee.setInterestRate(reqAccountInfoDTO.getInterestRate());
			accountChangeList.add(savingAccountFee);
		}
		reqAccountChangeDTO.setSavingAccountFeeList(accountChangeList);
		return reqAccountChangeDTO;
	}
	
	@Override
	public TaxFaultTask accountChangeExceptionJob(String reqJSON, String portCode, Integer faultTaskId) {
		logger.info("进入账户变更上传异常任务服务");
		ThirdSendResponseDTO thirdSendResponse = new ThirdSendResponseDTO();
		List<ReqBusinessDetailDTO> reqBusinessDetailList = new ArrayList<ReqBusinessDetailDTO>();
		TaxFaultTask faultTask = taxFaultTaskMapper.selectByPrimaryKey(faultTaskId);
		try {
			ReqBusinessDTO businessDTO = commonCodeService.initReqBusinessDTO();
			ParamHeadDTO paramHead = new ParamHeadDTO();
			CoreRequestHead coreRequestHead = new CoreRequestHead();
			List<ReqAccountInfoDTO> reqAccountInfoList = new ArrayList<ReqAccountInfoDTO>();
			//1. 解析请求报文
			//单笔请求
			if (ENUM_HX_SERVICE_PORT_CODE.ACCONUT_CHANGE_ONE.code().equals(portCode)) {
				ReqAccountCoreDTO reqAccountCoreDTO = JSONObject.parseObject(reqJSON, ReqAccountCoreDTO.class);
				ReqAccountInfoDTO reqAccountInfoDTO = (ReqAccountInfoDTO) reqAccountCoreDTO.getBody();
				reqAccountInfoList.add(reqAccountInfoDTO);
				coreRequestHead = reqAccountCoreDTO.getRequestHead();
			//多笔请求	
			} else if (ENUM_HX_SERVICE_PORT_CODE.ACCONUT_CHANGE_MORE.code().equals(portCode)){
				ReqAccountMoreChangeCoreDTO reqAccountMoreChangeCoreDTO = JSONObject.parseObject(reqJSON, ReqAccountMoreChangeCoreDTO.class);
				ReqAccountMoreChangeDTO reqAccountMoreChangeDTO = (ReqAccountMoreChangeDTO) reqAccountMoreChangeCoreDTO.getBody();
				reqAccountInfoList = reqAccountMoreChangeDTO.getSavingAccountFeeList();
				coreRequestHead = reqAccountMoreChangeCoreDTO.getRequestHead();
			} else {
				throw new BusinessDataErrException("请求接口编码有误! 错误接口编码为："+portCode);
			}
			//2. 封装头部信息
			paramHead.setAreaCode(coreRequestHead.getAreaCode());
			paramHead.setRecordNum(coreRequestHead.getRecordNum());
			paramHead.setSerialNo(coreRequestHead.getSerialNo());
			paramHead.setPortCode(portCode);
			ThirdSendDTO thirdSendDTO = new ThirdSendDTO();
			EbaoServerPortDTO ebaoServerPort = null;
			Holder<ResponseHeader> responseHeaderHolder = new Holder<ResponseHeader>();
			Holder<ResponseBody> responseBodyHolder = new Holder<ResponseBody>();
			// 预约码处理方式
			if(ENUM_DISPOSE_TYPE.APPOINTMENT.code().equals(faultTask.getDisposeType())){
				//3. 封装请求中保信数据
				paramHead.setRecordNum("1"); //异步请求接口请求记录数为1
				BookSequenceDTO bookSequence = new BookSequenceDTO();
				bookSequence.setBookingSequenceNo(faultTask.getRemark());
				thirdSendDTO = commonCodeService.createThirdSend(ENUM_EBAO_SERVICE_PORT_CODE.ACCONUT_CHANGE_APPOINTMENT.code(), paramHead, bookSequence);
				ebaoServerPort = commonCodeService.queryEBaoServerInfoByPortCode(ENUM_EBAO_SERVICE_PORT_CODE.ASYN_RESULT_QUERY.code());
				logger.info("多笔账户变更上传（请求中保信）JSON 数据内容："+JSONObject.toJSONString(thirdSendDTO));
				String portUrl = ebaoServerPort.getPortUrl();
				URL wsdlLocation = new URL(portUrl);
				AsynResultQueryService_Service service = new AsynResultQueryService_Service(wsdlLocation);
				AsynResultQueryService servicePort = service.getAsynResultQueryServicePort();
				BindingProvider bp = (BindingProvider) servicePort;
				bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, portUrl);
				servicePort.asynResultQuery(thirdSendDTO.getHead(), thirdSendDTO.getBody(),responseHeaderHolder, responseBodyHolder);
			}else if(ENUM_DISPOSE_TYPE.ASYNC.code().equals(faultTask.getDisposeType()) || ENUM_DISPOSE_TYPE.ERROR.code().equals(faultTask.getDisposeType())){
				// 将账户变更上传请求dto转换为中保信账户变更上传请求dto
				ReqAccountChangeDTO reqAccountChangeDTO = this.transforDTO(reqAccountInfoList);
				thirdSendDTO = commonCodeService.createThirdSend(ENUM_EBAO_SERVICE_PORT_CODE.ACCONUT_CHANGE.code(), paramHead, reqAccountChangeDTO);
				ebaoServerPort = commonCodeService.queryEBaoServerInfoByPortCode(ENUM_EBAO_SERVICE_PORT_CODE.ACCONUT_CHANGE.code());
				logger.info("异常任务 - 账户变更上传（请求中保信）JSON 数据内容(错误或异常类型)："+JSONObject.toJSONString(thirdSendDTO));
				String portUrl = ebaoServerPort.getPortUrl();
				URL wsdlLocation = new URL(portUrl);
				PolicyAccountService_Service service = new PolicyAccountService_Service(wsdlLocation);
				PolicyAccountService  servicePort = service.getPolicyAccountServicePort();
				BindingProvider bp = (BindingProvider) servicePort;
				bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, portUrl);
				servicePort.account(thirdSendDTO.getHead(),  thirdSendDTO.getBody(), responseHeaderHolder, responseBodyHolder);
			}else{
				throw new BusinessDataErrException("异常类型有误! 错误异常类型为："+ENUM_DISPOSE_TYPE.getEnumValueByKey(faultTask.getDisposeType()));
			}
			ResponseHeader responseHeader = responseHeaderHolder.value;
			ResponseBody responseBody = responseBodyHolder.value;
			logger.info("异常任务 - 账户变更上传（中保信响应）JSON 数据内容："+responseBody.getJsonString());
			ResponseJSON responseJSON = new ResponseJSON();
			responseJSON.setResponseBody(responseBody);
			responseJSON.setResponseHeader(responseHeader);
			// 如果是异步类型需要记录日志
			if(ENUM_DISPOSE_TYPE.ASYNC.code().equals(faultTask.getDisposeType())){
				SendLogDTO sendLog = new SendLogDTO();
				sendLog.setSerialNo(paramHead.getSerialNo());
				sendLog.setPortCode(ENUM_EBAO_SERVICE_PORT_CODE.ACCONUT_CHANGE.code());
				sendLog.setRequestContent(JSONObject.toJSONString(thirdSendDTO));
				sendLog.setResponseContent(JSONObject.toJSONString(responseJSON));
				sendLog.setTargetCode(ENUM_SENDSERVICE_CODE.EBAO.code());
				sendLog.setState(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
				sendLog.setDescription(ENUM_BZ_RESPONSE_RESULT.SUCCESS.description());
				commonCodeService.addLogSend(sendLog);
			}
			// 初始化头部错误信息
			String messageBody = ENUM_BZ_RESPONSE_RESULT.FAIL.description();
			//5. 封装返回核心dto;
			if (ENUM_RESULT_CODE.SUCCESS.code().equals(responseHeader.getResultCode())
					|| ENUM_RESULT_CODE.INPUT_LOCALITY_SUCCESS.code().equals(responseHeader.getResultCode())) {
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
				thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.SUCCESS.description());
			}else if(ENUM_RESULT_CODE.REQ_AWAIT.code().equals(responseHeader.getResultCode())){
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.code());
				thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.description());
			}else{
				thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.FAIL.code());
				List list = responseHeader.getResultMessage().getMessage();
				if(list != null && list.size() > 0){
					StringBuffer sbStr = new StringBuffer(); 
					for(String mess : responseHeader.getResultMessage().getMessage()){
						sbStr.append(mess).append("|");
					}
					String message = messageBody = sbStr.substring(0, sbStr.length()-1).toString();
					thirdSendResponse.setResultDesc(message);
				}else{
					thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.FAIL.description());
				}
			}
			boolean isRegisterFaulTask = false;
			List<AccountChangeResultDTO> accountChangeResultList = new ArrayList<AccountChangeResultDTO>();
			if(!StringUtil.isEmpty(responseBody.getJsonString())){
				//封装返回核心的DTO
				ResAccountChangeDTO resAccountChangeDTO = JSONObject.parseObject(responseBody.getJsonString(), ResAccountChangeDTO.class);
				if (null != resAccountChangeDTO.getSavingAccountFeeList()) {
					// 成功记录数
					Integer successNum = 0;
					// 失败记录数
					Integer failNum = 0;
					//把中保信返回的对象中的每一条信息都传给核心返回的DTO
					for (AccountChangeAffDTO accountChangeAffDTO : resAccountChangeDTO.getSavingAccountFeeList()) {
						AccountChangeResultDTO accountChangeResultDTO=new AccountChangeResultDTO();
						accountChangeResultDTO.setComFeeId(accountChangeAffDTO.getComFeeId());
						accountChangeResultDTO.setAccountFeeSequenceNo(accountChangeAffDTO.getAccountFeeSequenceNo());
						for (ReqAccountInfoDTO reqAccountInfoDTO : reqAccountInfoList) {
							if(reqAccountInfoDTO.getComFeeId().equals(accountChangeAffDTO.getComFeeId())){
								accountChangeResultDTO.setBizNo(reqAccountInfoDTO.getBizNo());
								EBResultCodeDTO eBResultCode = accountChangeAffDTO.getResult();
								HXResultCodeDTO hxResultCode = new HXResultCodeDTO();
								hxResultCode.setResultCode(eBResultCode.getResultCode());
								String message = "";
								if(null != eBResultCode.getResultMessage()){
									StringBuffer sbStr = new StringBuffer(); 
									for(String mess : eBResultCode.getResultMessage()){
										sbStr.append(mess).append("|");
									}
									message = sbStr.substring(0, sbStr.length()-1).toString();
								}
								hxResultCode.setResultMessage(message);
								accountChangeResultDTO.setResult(hxResultCode);
								accountChangeResultList.add(accountChangeResultDTO);
								//记录成功和失败记录数
								if(ENUM_RESULT_CODE.SUCCESS.code().equals(eBResultCode.getResultCode())){
									successNum += 1;
									this.addAccountMore(reqAccountInfoDTO, accountChangeResultDTO);
								}else{
									failNum += 1;
									ReqBusinessDetailDTO reqBusinessDetailDTO = commonCodeService.initReqBusinessDetailDTO(paramHead);
									reqBusinessDetailDTO.setResultCode(ENUM_BUSINESS_RESULR.FAIL.code());
									reqBusinessDetailDTO.setResultMessage(message);
									reqBusinessDetailList.add(reqBusinessDetailDTO);
								}
							}
						}
					}
					// 判断多笔还是单笔返回
					if (ENUM_HX_SERVICE_PORT_CODE.ACCONUT_CHANGE_ONE.code().equals(portCode)) {
						thirdSendResponse.setResJson(accountChangeResultList.get(0));
					} else if (ENUM_HX_SERVICE_PORT_CODE.ACCONUT_CHANGE_MORE.code().equals(portCode)) {
						thirdSendResponse.setResJson(accountChangeResultList);
					}
					// 登记请求记录
					businessDTO.setReqSuccessNum(successNum);
					businessDTO.setReqFailNum(failNum);
					isRegisterFaulTask = true;
				}else{
					BookSequenceDTO bookSequence = JSONObject.parseObject(responseBody.getJsonString(),BookSequenceDTO.class);
					// 插入异常任务表
					faultTask.setRemark(bookSequence.getBookingSequenceNo());
					faultTask.setDisposeType(ENUM_DISPOSE_TYPE.APPOINTMENT.code());
					thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.code());
					thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.description());
				}
			}else{
				businessDTO.setReqFailNum(responseHeader.getRecordNum());
				thirdSendResponse.setResJson(messageBody);
				for (int i = 0; i < responseHeader.getRecordNum(); i++) {
					ReqBusinessDetailDTO reqBusinessDetailDTO = commonCodeService.initReqBusinessDetailDTO(paramHead);
					reqBusinessDetailDTO.setResultCode(ENUM_BUSINESS_RESULR.FAIL.code());
					reqBusinessDetailDTO.setResultMessage(thirdSendResponse.getResultDesc());
					reqBusinessDetailList.add(reqBusinessDetailDTO);
				}
			}
			if (isRegisterFaulTask) {
				// 添加失败交易记录
				commonCodeService.addReqBusinessDetail(reqBusinessDetailList);
				businessDTO.setRequetNum(responseHeader.getRecordNum());
				commonCodeService.addReqBusinessCollate(businessDTO);			
				faultTask.setDisposeResult(ENUM_BZ_RESPONSE_RESULT.SUCCESS.code());
			}else{
				faultTask.setDisposeResult(ENUM_BZ_RESPONSE_RESULT.FAIL.code());
			}
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("账户变更上传异常任务服务方法处理发生异常! 异常信息为："+e.getMessage());
			thirdSendResponse.setResJson(e.getMessage());
			thirdSendResponse.setResultCode(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.code());
			thirdSendResponse.setResultDesc(ENUM_BZ_RESPONSE_RESULT.EXCEPTION.description());
			faultTask.setDisposeResult(ENUM_BZ_RESPONSE_RESULT.FAIL.code());
			if(ENUM_DISPOSE_TYPE.APPOINTMENT.code().equals(faultTask.getDisposeType())){
				faultTask.setDisposeType(ENUM_DISPOSE_TYPE.APPOINTMENT.code());
			}else{
				faultTask.setDisposeType(ENUM_DISPOSE_TYPE.ERROR.code());
			}
		} finally{
			faultTask.setSuccessMessage(JSONObject.toJSONString(thirdSendResponse));
			faultTask.setDisposeDate(DateUtil.getCurrentDate());
			taxFaultTaskMapper.updateByPrimaryKeySelective(faultTask);
		}
		return faultTask;
	}
	/**
	 * 数据持久化(多笔)
	 * @param reqAccountInfoList
	 * @param i
	 * @param accountChangeResultDTO
	 */
	private void addAccountMore(ReqAccountInfoDTO reqAccountInfo, AccountChangeResultDTO accountChangeResultDTO) {
		try {
			//业务表持久化
			TaxContAccountTrack taxContAccountTrack=new TaxContAccountTrack();
			taxContAccountTrack.setContNo(reqAccountInfo.getPolicyNo());
			taxContAccountTrack.setRiskCode(reqAccountInfo.getComCoverageCode());
			taxContAccountTrack.setRiskName(reqAccountInfo.getComCoverageName());
			taxContAccountTrack.setFeeId(accountChangeResultDTO.getComFeeId());
			taxContAccountTrack.setFeeDate(DateUtil.parseDate(reqAccountInfo.getFeeDate()));
			taxContAccountTrack.setFeeType(reqAccountInfo.getFeeType());
			taxContAccountTrack.setFeeAmount(reqAccountInfo.getFeeAmount());
			taxContAccountTrack.setAffectStartDate(DateUtil.parseDate(reqAccountInfo.getRiskCoverageStartDate()));
			taxContAccountTrack.setAffectEndDate(DateUtil.parseDate(reqAccountInfo.getRiskCoverageEndDate()));
			taxContAccountTrack.setInterestRate(reqAccountInfo.getInterestRate());
			taxContAccountTrack.setBalanceAmount(reqAccountInfo.getBalanceAmount());
			taxContAccountTrack.setRebackDetailId(reqAccountInfo.getRevComFeeId());
			taxContAccountTrack.setRcState(ENUM_RC_STATE.EFFECTIVE.getCode());
			taxContAccountTrack.setCreateDate(DateUtil.getCurrentDate());
			taxContAccountTrack.setModifyDate(DateUtil.getCurrentDate());
			taxContAccountTrack.setCreatorId(SystemConstants.SYS_OPERATOR);
			taxContAccountTrack.setModifierId(SystemConstants.SYS_OPERATOR);
			taxContAccountTrackMapper.insert(taxContAccountTrack);
		} catch (Exception e) {
			e.printStackTrace();
			logger.error("账户变更上传数据持久化失败"+ e.getMessage());
		}
	}
}